TITL DAI FIRMWARE CA01-CBBE V1.1 ORG :CA01 * * * ***************************** * MEMORY MANAGEMENT ROUTINE * ***************************** * * This routine is used to obtain and release * memory for its display, as the mode changes. * * Entry: HL: Lowest screen RAM byte required. * CY=1: Space to this point at least is * now required. Additional space * may not be released. * CY=0: Space is held to or below this * point. Any space held below this * point is no longer required. * Exit: CY=1: O.K. * CY=0: No space available. * AFBCDE preserved. * *ASKRM SMKRM NOP PUSH PSW PUSH D JNC :CA1B If space not reqd anymore XCHG Lowest byte in DE LHLD :02A5 Get bottom screen RAM CALL :DE14 Check for overflow JC :CA1E If OK LHLD :02A3 Get begin free RAM XCHG and store it in DE CALL :DE14 Still free RAM available? JC :CA21 If not ASR10 SHLD :02A5 Update bottom screen RAM ASR20 JMP :CEAD Return, set CY=1 REM * If no RAM space available: REM ASR30 POP D JMP :CEB1 Return, set CY=0 * ******************************************* * EMERGENCY STOP ROUTINE (Graphics modes) * ******************************************* * * This routine is used if no sufficient space for * a A-mode is available. * * ************************** * EMERGENCY STOP ROUTINE * ************************** * * No change in execution, only using a new entry on * 'Run NEW'. * EMSTP CALL :DEB1 Run NEW with default heap MVI A,:FF RST 5 Change to mode 0 DATA :18 CALL :CEE4 Select ROM-bank 0; Run error DBL :DB89 'OUT OF SPACE FOR MODE' JMP :C818 Return to BASIC monitor * ****************************************** * FIND STRING BASIC INSTRUCTION IN TABLE * ****************************************** * * Looks for table entry whose name is the initial * string of input, beginning at C'th position. * REMARK: Variables, beginning with a reserved * string are not allowed. * * Entry: HL: Startaddress table. * C : Position char on current line. * E : Number of info bytes -1. * Exit: If found: CY=1: * HL: Address in table where string * can be found. * C : Position on current line after * last char. * A : Last byte of string typed in. * BE preserved, D=0. * If not found: CY=0: * C : Points to next char. * HL: Points after end of table. * BE preserved. A,D=0. * LOOKC CALL :DDD2 Get char from line, REM neglect TAB and space LKC10 MOV D,M Get length byte of string INX H Points to 1st stringchar. MOV A,D ORA A Is length zero? RZ Then abort PUSH B Save position of 1st char LKC20 CALL :DDE0 Get char from line INR C Points to next char on line CMP M Is it identical to the REM one in table? INX H Points to next char in table JNZ :CA4E If not identical DCR D Else: decr string length JNZ :CA3D Get evt. next byte to check XTHL cancell PUSH B POP H STC CY=1 RET REM * If strings not identical: REM LKC30 MOV A,D Get string length ADD E Add 2 CALL :DE30 Add A to HL; HL points now REM to next string in table. POP B Restore C=1 JMP :CA37 Start check on next string * ***************** * TABLE LOOK UP * ***************** * * Finds an entry in a look-up table. * LOOK used for symboltable, LOOKX for table of * Basic functions (CFE6). * * Table format: * [type/length][name][type/length][info] * * Entry: B: Points to start name in input. * D: Type/length of name in input * high nibble: type; low nibble: length. * HL: Startaddress look-up table. * Exit: If not found: CY=0: * HL points to 0 byte at table end. * ABCD preserved, E corrupted. * If found: CY=1: * HL points to T/L of entry found. * E indicates how manyth entry. * ABC preserved. * LOOK LHLD :02A1 Get startaddr symtab * LOOKX STC CY=1 PUSH PSW PUSH B MVI E,:FF LK10 INR E Entry count MOV A,M Get T/L name in table ORA A JZ :CA8B Abort if end table reached CMP D Compare with wanted T/L JZ :CA6F Jump if found LK15 CALL :CAAE Calc addr next entry JMP :CA5F Check next entry REM * If T/L of name O.K.: REM LK20 POP B PUSH B MOV C,B PUSH D MOV A,D Get wanted T/L of name ANI :0F Length name only MOV D,A in D PUSH H Save begin table entry LK30 INX H CALL :DDE0 Get char from line CMP M Compare char of name JNZ :CA8F If not correct name REM * If char. identical: REM INR C Points to next char DCR D Decr length JNZ :CA78 Check next char if not REM ready INX H Points after name in table POP D POP D POP B POP PSW CY=1: Entry found RET REM * If end of look-up table reached: REM LK40 POP B POP PSW CMC CY=0: No entry found RET REM * If characters not identical: REM LK50 POP H POP D MOV A,D Length in A JMP :CA69 Look further * ************************************** * FIND A VARIABLE IN THE SYMBOLTABLE * ************************************** * * Routine skips through successive symtab entries * from beginning till past the place pointed by HL. * * Entry: HL points to 1st byte required variable. * Exit: HL points to (if found) or past (if not * found) address required in symbol table. * AFBCDE preserved. * FNAME PUSH PSW PUSH D XCHG Reqd addr in DE LHLD :02A1 Get startaddr symtab FNM10 PUSH H CALL :CAAE Calc addr next variable CALL :DE14 Reqd variable reached ? JNC :CAAA Quit if true INX SP ) Cancel Push H INX SP ) JMP :CA9B Skip next variable FNM20 POP H POP D POP PSW RET * ************************************************** * CALCULATE ADDRESS NEXT VARIABLE IN SYMBOLTABLE * ************************************************** * * Adds length of name of variable + length of value * of variable to beginaddress. * * DADD: variable = length/name/length/value. * DADR: variable = length/name. * * Entry: HL points to 1st byte of current variable. * Exit: HL points to next variable in symtab. * DADD CALL :CAB1 Add length name to HL DADR MOV A,M Get info T/L byte INX H Add 1 ANI :0F Length only JMP :DE30 Add length info to HL * ********************************************** * INSERT A VARIABLE NAME IN THE SYMBOL TABLE * ********************************************** * * Entry: HL points to end symtab. * B points to start of name in input. * E number of bytes of info to reserve. * D T/L byte of name. * Exit: HL points to info T/L byte. * AFBCDE preserved. * LOOKI PUSH PSW PUSH B MOV C,B Input pos. in C PUSH D PUSH D PUSH H MOV A,D T/L name in A ANI :0F Name length only ADD E Add length info INR A INR A +2 (length new entry) CALL :DE30 Calc new end symtab -1 XCHG LHLD :02A5 Get bottom screen RAM XCHG CALL :DE14 Compare DE-HL MVI A,:1B JNC :D9F5 Run 'OUT OF MEMORY' if REM not sufficient free RAM MVI M,:00 New 'end table' flag INX H HL is new end symtab SHLD :02A3 Store end symtab POP H Get old end symtab POP D Get T/L info MOV M,D Into symtab INX H MOV A,D ANI :70 Get type only ORA E Set low nibble for length MOV E,A MOV A,D Get length name ANI :0F Max. 15 bytes MOV D,A Length in D for count LKI10 CALL :DDE0 Get char from line MOV M,A Char into symtab INR C Pnts to next char on line INX H Next pos in symtab DCR D Decr length name JNZ :CAE7 Next char if not ready MOV M,E Info T/L into symtab POP D POP B POP PSW RET * ********************************* * FIND LINENUMBER IN TEXTBUFFER * ********************************* * * Entry: HL: requested linenumber. * Exit: ABCDE preserved. F corrupted. * CY=1: Linenr found: * HL points to address textline. * CY=0: Not found: * Z=0: HL points to address textline * with next higher linenumber. * Z=1: End of textbuffer reached. * FINDL PUSH B PUSH PSW PUSH D MVI B,:00 XCHG Req. linenr in DE LHLD :029F Get startaddr textbuf FDL05 MOV C,B Length prev. instr in C MVI B,:00 DAD B Add this length to beginaddr FDL10 MOV B,M Get length current instr MOV A,B in A ORA A INX H Pnts to hibyte linenr JZ :CB1D Abort if at end textbuf MOV A,D Get hibyte reqd linenr. CMP M Test high order bits JC :CB1C Abort if reqd nr lower than REM current one (nr > reqd) JNZ :CAFF Next textline (nr < reqd) INX H Pnts to lobyte linenr MOV A,E Get lobyte reqd linenr CMP M DCX H JC :CB1C Abort if reqd nr lower than REM current one (nr > reqd) JNZ :CAFF Next textline if not found REM (nr < reqd) FDL20 CMC Line found: CY=1 FDL30 DCX H POP D POP B MOV A,B POP B RET * ****************************** * EMPTY SYMBOLTABLE AND HEAP * ****************************** * * Zeroes all variables, all pointers in the symtab, * kill all arrays, strings or stringarrays (zero the * pointers) referenced by the symtab by setting the * msb of the sizebit =1. Basic program is moved to a * location corresponding to the Heapsize. * * Exit: All registers preserved. * SCRATC PUSH PSW PUSH B PUSH D PUSH H LHLD :02A1 Get startaddr symtab SCT10 MOV A,M ) get name length ANI :0F ) JZ :CB53 Abort if at end symtab CALL :CAB1 HL pnts to info length byte MOV A,M ) Get type ANI :F0 ) CPI :40 JNC :CB4D If array INX H CPI :20 JZ :CB47 If string REM * If numeric variable: REM CALL :CB9E Set value is 0 (4 bytes) JMP :CB2A Next entry REM * If string variable: REM SCT30 CALL :CBA8 Erase string reference in REM symbtab and Heap JMP :CB2A Next entry REM * If array: REM SCT40 CALL :CB5B Erase array JMP :CB2A Next entry REM * If ready: REM SCT90 CALL :DECA Organise HEAP + buffers LC188 POP H POP D POP B POP PSW RET * *************** * ERASE ARRAY * *************** * * The pointer is zeroed, the array size is erased * (msb=1). For stringarrays: zeroes all pointers * in the array and erase the string in the Heap. * * Entry: HL points to T/L byte of info after a * symtab name of an array. * Exit: HL points to next symtab entry. * AFBCDE preserved. * EARRAY PUSH D PUSH B PUSH PSW MOV A,M Get type info ANI :30 PUSH PSW Save type only CALL :CE51 ) Get addr of array in INX H ) Heap in DE, MOV D,M ) Kill pointer in the MVI M,:00 ) symboltable INX H Pnts after symtab entry MOV A,D ORA E JZ :CB99 Abort if entry was already 0 XCHG Arrayaddr in HL DCX H DCX H Pnts to 1st byte Heap entry MOV B,M Get 1st byte CALL :D236 Clear heap entry by msb=1 POP PSW Get type info PUSH PSW CPI :20 String ? PUSH D Save stringpointer JNZ :CB98 Abort if not string REM * If string array: REM INX H MOV C,M Get length Heap entry INX H MOV E,M Get dimension INR E MOV A,E CALL :DE30 Calc beginaddr stringpntrs MOV A,C SUB E Calc length pntr area MOV C,A in C JNC :CB8E DCR B EAR10 CALL :CBA8 Erase stringreference in REM symtab and Heap DCX B DCX B Update length pntr area MOV A,B ORA C JNZ :CB8E Next string if not ready REM * If ready: REM EAR20 POP H Get symtab pntr EAR30 POP PSW POP PSW POP B POP D RET * *********************************************** * CLEAR A NUMERIC VARIABLE IN THE SYMBOLTABLE * *********************************************** * * Loads '0' into 4 consecutive memory locations. * * Entry: Startaddress in HL. * Exit: A=0, HL points to next byte. * BCDEF preserved. * ZFPINT XRA A MOV M,A INX H MOV M,A INX H MOV M,A INX H MOV M,A INX H RET * ******************************************** * ERASE STRINGREFERENCE IN HEAP AND SYMTAB * ******************************************** * * The pointer in the symtab is set to '0', the * msb of the sizebyte of the Heap entry is set * to 1. * * Entry: HL points to stringpointer in symtab. * Exit: HL points after this pointer. * DE stringpointer. * BC preserved, AF corrupted * RSVHL MOV E,M ) Stringpointer MVI M,:00 ) in DE and then INX H ) erased. MOV D,M ) MVI M,:00 ) INX H PUSH H LHLD :029F Get startaddr textbuf XCHG in DE; stringpntr in HL MOV A,H ORA L Stringpntr is already 0 ? CNZ :DE14 If not: test if end of REM heap reached CC :D187 If not: clear heap entry POP H RET * * * UNL ASKRM EQU SMKRM LST END